Ext.ns('AIR2.Drawer');
/***************
 * AIR2 Drawer API
 *
 * Static API functions for adding, removing, and modifying AIR2 Bins and
 * related data.
 *
 * @function AIR2.Drawer.API.addItems
 * @param {Ext.data.Record} rec
 *   The bin record to add items to.
 * @param {Object/Array/Function/String} items
 *   To add a search, pass an Object of the form {q:, i:, total:}. To add basic
 *   items, pass in an Array of UUID strings, or a single UUID string. To add
 *   related items, pass in an Array of Objects of the form {uuid:, reltype:}.
 *   You may also pass in a function that returns Objects {type:, uuid:}.
 * @param {Function} callback
 *   A function to call after the AJAX call completes. Must accept the
 *   parameters (radix, success).
 *
 * @function AIR2.Drawer.API.removeItems
 * @param {Ext.data.Record} rec
 * @param {Object/Array/Function/String} items
 * @param {Function} callback
 *
 * @function AIR2.Drawer.API.merge
 * @param {Ext.data.Record} rec
 * @param {Array} mergeRecs
 *   Array of Bin Ext.data.Records, whose contents will be merged into rec.
 * @param {Function} callback
 *
 * @function AIR2.Drawer.API.random
 * @param {Ext.data.Record} rec
 * @param {Integer} numToCreate
 * @param {Integer} sizeOfEach
 * @param {Function} callback
 *
 */
AIR2.Drawer.API = function() {
    var binAjax = function(uuid, params, callbackFn, scope) {
        if (!callbackFn) callbackFn = function(){}; //empty function
        Ext.Ajax.request({
            method: 'PUT',
            url: AIR2.HOMEURL + '/batch/' + uuid + '/contents.json',
            params: params,
            scope: scope || this,
            callback: function(opts, success, resp) {
                if (success) {
                    var data = Ext.util.JSON.decode(resp.responseText);
                    var counts = {
                        insert: data.insert,
                        duplicate: data.duplicate,
                        invalid: data.invalid
                    };
                    callbackFn(data.radix, data.success, counts);
                }
                else {
                    callbackFn('server error!', false);
                }
            }
        });
    };
    var binUpdFn = function(data, success, counts, rec, callback) {
        if (success) {
            // explicitly modify data to avoid store events
            rec.data.batch_count = data.batch_count;
            var date = Date.parseDate(data.batch_last_use, "Y-m-d H:i:s");
            rec.data.batch_last_use = date;
        }
        callback(data, success, counts);
    };
    var formatItemsFn = function(input, batchType) {
        // robustly interrogate "input" and format it correctly
        if (Ext.isFunction(input)) return input();
        if (!Ext.isArray(input)) return formatItemsFn([input], batchType);

        var result = [];
        Ext.each(input, function(item) {
            var o = {type: batchType};

            // determine the uuid and related type (if any) of the item
            if (Ext.isString(item)) {
                o.uuid = item;
            }
            else {
                o.uuid = (Ext.isDefined(item.uuid)) ? item.uuid : item.id;
                if (Ext.isDefined(item.reltype) && item.reltype) o.reltype = item.reltype;
            }
            result.push(o);
        });

        return result;
    };

    return {
        addItems: function(rec, items, callback) {
            var myParams = {};
            if (Ext.isObject(items)) {
                //add search
                var search = {q:items.q, i:items.i, total:items.total};
                myParams.addsearch = Ext.util.JSON.encode(search);
            }
            else {
                // setup in the format the server expects
                var addUUIDs = formatItemsFn(items, rec.get('batch_type'));
                myParams.add = Ext.util.JSON.encode(addUUIDs);
            }

            // execute, with a callback hook to update batch_count/last_use
            binAjax(rec.get('batch_uuid'), myParams,
                binUpdFn.createDelegate(this, [rec, callback], true));
        },
        removeItems: function(rec, items, callback) {
            // setup in the format the server expects
            var rmvUUIDs = formatItemsFn(items, rec.get('batch_type'));
            var myParams = {remove: Ext.util.JSON.encode(rmvUUIDs)};
            binAjax(rec.get('batch_uuid'), myParams, callback);
        },
        merge: function(rec, mergeRecs, callback) {
            // get the UUIDs from the merge batches
            var mergeUUIDs = [];
            for (var i=0; i<mergeRecs.length; i++) {
                mergeUUIDs.push(mergeRecs[i].get('batch_uuid'));
            }
            var myParams = {merge: Ext.util.JSON.encode(mergeUUIDs)};
            binAjax(rec.get('batch_uuid'), myParams, callback);
        },
        random: function(rec, numToCreate, sizeOfEach, callback) {
            var randParams = {numbatches: (numToCreate && numToCreate > 0) ? numToCreate : 1};
            if (sizeOfEach) randParams.size = sizeOfEach;
            var myParams = {random: Ext.util.JSON.encode(randParams)};
            binAjax(rec.get('batch_uuid'), myParams, callback);
        }
    }
}();